package com.cr.dataprotect.interceptor;



import com.cr.dataprotect.bean.ProviderConfigBean;
import com.cr.dataprotect.manage.DesensitizationManage;
import com.cr.dataprotect.manage.IntegrityManage;
import com.cr.dataprotect.manage.SensitiveManage;
import com.cr.dataprotect.provider.AbstractProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.sql.Statement;
import java.util.Properties;

/**
 * 拦截Mybatis ResultSetHandler,对结果集进行拦截处理
 * <p>
 * 执行顺序：1.完整性保护校验 2.敏感字段解密 3.解密数据进行脱敏处理
 *
 * @author ChenRui
 * @since 2023.12.05
 */
@Intercepts({
        @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
@Slf4j
@Component
@Order(1)
public class ResultSetInterceptor extends AbstractProvider implements Interceptor {

    @Autowired
    private IntegrityManage integrityManage;
    @Autowired
    private SensitiveManage sensitiveManage;
    @Autowired
    private DesensitizationManage desensitizationManage;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        //在执行完成之后来处理，取执行的结果
        Object result = invocation.proceed();

        if (!super.hasProvider()) {
            //如果没配置敏感字段，则不需要处理
            return result;
        }
        ProviderConfigBean providerConfigBean = super.loadAllFieldConfig();
        //2.1.1.进行完整性保护校验
        if (MapUtils.isNotEmpty(providerConfigBean.getIntegrity())) {
            integrityManage.validateIntegrity(result, providerConfigBean.getIntegrity());

        }
        //2.2.对敏感字段进行解密
        if (MapUtils.isNotEmpty(providerConfigBean.getSensitive())) {
            result = sensitiveManage.decrypt(result, providerConfigBean.getSensitive());
        }
        //2.3.对配置数据脱敏
        if (MapUtils.isNotEmpty(providerConfigBean.getDesensitization())) {
            result = desensitizationManage.desensitizationData(result, providerConfigBean.getDesensitization());
        }

        return result;
    }

    /**
     * 对返回值对象的具体处理过程.
     *
     * @param resultObj 返回值对象
     * @throws IllegalAccessException 反射可能抛出的异常
     */
    private void process(Object resultObj) {
        if (resultObj == null) {
            return;
        }
    }

    @Override
    public Object plugin(Object target) {
        if (target instanceof ResultSetHandler) {
            return Plugin.wrap(target, this);
        }
        return target;
    }

    @Override
    public void setProperties(Properties properties) {
        //empty method
    }

}
